#ifndef _RequestDealer_H_
#define _RequestDealer_H_
#include <iostream>
#include <string>
#include <map>
#include "ParamHandler.h"
#include "../Utils/JsonUtil.h"

using namespace std;

class RequestDealer{
public:
	virtual string dealRequest(map<string,string> &param)=0;
protected:
	ParamHandler *handler;
	string dealHandler(ParamHandler *&handler,map<string,string> &param);
};

class NegotiationRequestDealer:public RequestDealer{
public:
	string dealRequest(map<string,string> &param) override;
};

class EncryptRequestDealer:public RequestDealer{
public:
	string dealRequest(map<string,string> &param) override;
};

class ARQRequestDealer:public RequestDealer{
public:
	string dealRequest(map<string,string> &param) override;
};

class HashRequestDealer:public RequestDealer{
public:
	string dealRequest(map<string,string> &param) override;
};

class DefRequestDealer:public RequestDealer{
public:
	string dealRequest(map<string,string> &param) override;
};

class DealerFactory{
public:
	RequestDealer* createRequestDealer(string operation);
};

//function defination of DealerFactory
RequestDealer* DealerFactory::createRequestDealer(string operation)
{
	if(operation=="negotiation"){
		return new NegotiationRequestDealer;
	}
	else if(operation=="encrypt"){
		return new EncryptRequestDealer;
	}
	else if(operation=="arq"){
		return new ARQRequestDealer;
	}
	else if(operation=="hash"){
		return new HashRequestDealer;
	}
	else if(operation=="def"){
		return new DefRequestDealer;
	}
	else{
		return nullptr;
	}
}

//function definaltion of RequestDealer
string RequestDealer::dealHandler(ParamHandler *&handler,map<string,string> &param)
{
	string result=handler->handleRequest(param);
	if(handler!=nullptr)
		delete handler;
	return result;
}

//function defination of  NegotiationRequestDealer
string NegotiationRequestDealer::dealRequest(map<string,string> &param) 
{
	string type=param["type"];
	if(type=="")
		return JsonUtil::get_response_json("please check your params!",false);
	string method=param["method"];
	if(method=="")
		return JsonUtil::get_response_json("please check your params!",false);
	handler=new  NegotiationParamHandler();
	return dealHandler(handler,param);
}

//function defination of EncryptRequestDealer
string EncryptRequestDealer::dealRequest(map<string,string> &param) 
{
	handler=new EncryptParamHandler();
	return dealHandler(handler,param);
}

//function defination of ARQRequestDealer
string ARQRequestDealer::dealRequest(map<string,string> &param)
{
	string round=param["round"];
	if(round=="")
		return JsonUtil::get_response_json("please check your params!",false);
	string rto=param["RTO"];
	if(rto=="")
		return JsonUtil::get_response_json("please check your params!",false);
	string limit=param["limit"];
	if(limit=="")
		return JsonUtil::get_response_json("please check your params!",false);
	handler=new ARQParamHandler();
	return dealHandler(handler,param);
}

//function defination of HashRequestDealer
string HashRequestDealer::dealRequest( map<string,string> &param)
{
	string method=param["method"];
	if(method=="")
		return JsonUtil::get_response_json("please check your params!",false);
	handler=new HashParamHandler();
	return dealHandler(handler,param);
}

//function defination of DefRequestDealer
string DefRequestDealer::dealRequest(map<string,string> &param)
{
	handler=new DefParamHandler();
	return dealHandler(handler,param);
}

#endif